home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-08-14 | 16.3 KB | 672 lines | [TEXT/CWIE] |
- // PickMeshShapePart.c
- //
- // This demonstrates how to use picks to test which parts of a mesh geometry have
- // been hit. When the mesh is picked the fPickParts value set from the ShapeParts
- // menu controls the parts tested: object, face, edge, or vertex. As the returned
- // hits in the pick are processed the corresponding part of the mesh is draw in a
- // different color and the name of that part is displayed in the window's upper
- // left corner.
- //
- // The vertex and edge tolerance levels set in CreatePick() control how close the
- // window point pick must be to the given part.
- //
- // Robert Dierkes - November 11, 1995
- //
- // ©1994-95 Apple computer Inc., All Rights Reserved
- //
-
- // system headers
- #include <Windows.h>
-
- // for QuickDraw 3D
- #include "QD3D.h"
- #include "QD3DMath.h"
- #include "QD3DDrawContext.h"
- #include "QD3DShader.h"
- #include "QD3DGroup.h"
- #include "QD3DPick.h"
-
-
- #include "PickMeshShapePart.h"
-
-
- //-------------------------------------------------------------------------------------------
- // function prototypes
-
- void TickDelay(
- long time);
-
- TQ3Status DoGroupPicking(
- TQ3ViewObject view,
- TQ3GroupObject group,
- TQ3PickObject pick);
-
- void GetRandomRGBColor(
- TQ3ColorRGB *pColorRGB);
-
- TQ3Status ChangeMeshFaceColor(
- TQ3GeometryObject meshGeo,
- TQ3MeshFace meshFace,
- DocumentPtr theDocument);
-
- TQ3Status ChangeMeshEdgeColor(
- TQ3GeometryObject meshGeo,
- TQ3MeshEdge meshEdge,
- DocumentPtr theDocument);
-
- TQ3Status ChangeMeshVertexColor(
- TQ3GeometryObject meshGeo,
- TQ3MeshVertex meshVertex,
- DocumentPtr theDocument);
-
- TQ3Status HandleMeshShapePart(
- TQ3GeometryObject geometry,
- TQ3ShapePartObject shapePart,
- DocumentPtr theDocument);
-
- TQ3Status HandleMeshPickHits(
- TQ3PickObject pick,
- DocumentPtr theDocument);
-
- TQ3Status CreatePick(
- TQ3PickObject *pPick);
-
-
- //-------------------------------------------------------------------------------------------
- //
-
- #define kDelay 30
- #define kTextLocationX 30
- #define kTextLocationY 30
-
- static TQ3PickObject gPick = NULL;
-
-
-
- //-----------------------------------------------------------------------------
- //
- // InitPicking
-
-
- TQ3Status InitPicking(
- void)
- {
- return CreatePick(&gPick);
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // ExitPicking
-
- TQ3Status ExitPicking(
- void)
- {
- if (gPick != NULL) {
- Q3Object_Dispose(gPick);
- gPick = NULL;
- }
-
- return kQ3Success;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // TickDelay
-
- static
- void TickDelay(
- long time)
- {
- long ticks,
- startTicks;
-
- startTicks = ticks = TickCount();
-
- while (ticks - startTicks != time ) {
- ticks = TickCount();
- }
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // DoGroupPicking
-
- static
- TQ3Status DoGroupPicking(
- TQ3ViewObject view,
- TQ3GroupObject group,
- TQ3PickObject pick)
- {
- TQ3Status status;
- TQ3ViewStatus viewStatus;
-
- if ((status = Q3View_StartPicking(view, pick)) == kQ3Failure)
- return status;
-
- do {
- status = Q3DisplayGroup_Submit(group, view);
-
- viewStatus = Q3View_EndPicking(view);
- } while (viewStatus == kQ3ViewStatusRetraverse);
-
- if (viewStatus != kQ3ViewStatusDone) {
- status = kQ3Failure;
- }
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // GetRandomRGBColor
-
- static
- void GetRandomRGBColor(
- TQ3ColorRGB *pColorRGB)
- {
- unsigned long ticks;
-
- ticks = TickCount();
- Q3ColorRGB_Set(pColorRGB,
- (ticks % 10) / 10.0,
- (ticks % 100) / 100.0,
- (ticks % 1000) / 1000.0);
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // ChangeMeshFaceColor
-
- static
- TQ3Status ChangeMeshFaceColor(
- TQ3GeometryObject meshGeo,
- TQ3MeshFace meshFace,
- DocumentPtr theDocument)
- {
- TQ3Status status;
- TQ3AttributeSet attributeSet;
- TQ3ColorRGB colorRGB;
-
- status = kQ3Failure;
-
- if (meshGeo == NULL ||
- meshFace == NULL) {
- return status;
- }
-
- /* Get the face attributes */
- if ((status = Q3Mesh_GetFaceAttributeSet(meshGeo, meshFace, &attributeSet)) == kQ3Failure) {
- return status;
- }
-
- /* Create an attributes if none */
- if (attributeSet == NULL) {
- if ((attributeSet = Q3AttributeSet_New()) == NULL) {
- return kQ3Failure;
- }
- }
-
- GetRandomRGBColor(&colorRGB);
- if ((status = Q3AttributeSet_Add(attributeSet, kQ3AttributeTypeDiffuseColor, &colorRGB)) == kQ3Success) {
-
- char partTypeString[] = {"\pFace"};
-
- /* Set new face color */
- status = Q3Mesh_SetFaceAttributeSet(meshGeo, meshFace, attributeSet);
-
- /* Redraw the mesh */
- DrawDocumentData(theDocument);
- MoveTo(kTextLocationX, kTextLocationY);
- DrawText((void *) partTypeString, 1, (short) partTypeString[0]);
- TickDelay(kDelay);
-
- /* Remove new face color */
- status = Q3Mesh_SetFaceAttributeSet(meshGeo, meshFace, NULL);
- DrawDocumentData(theDocument);
- }
-
- Q3Object_Dispose(attributeSet);
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // ChangeMeshEdgeColor
-
- static
- TQ3Status ChangeMeshEdgeColor(
- TQ3GeometryObject meshGeo,
- TQ3MeshEdge meshEdge,
- DocumentPtr theDocument)
- {
- TQ3Status status;
- TQ3AttributeSet attributeSet1,
- attributeSet2;
- TQ3MeshVertex meshVertex1,
- meshVertex2;
- TQ3ColorRGB colorRGB;
-
- status = kQ3Failure;
-
- if ((meshGeo == NULL) ||
- (meshEdge == NULL) ||
- (theDocument == NULL)) {
- debugstr("ChangeMeshEdgeColor: NULL parameter passed");
- return status;
- }
-
- attributeSet1 = NULL;
- attributeSet2 = NULL;
-
- /*
- * Set color on both vertices of this edge
- *
- * We change the vertex attributes instead of the edge attributes because we can only
- * see the effects of an edge attribute when the fill style is kQ3FillStyleEdges. We
- * could use kQ3FillStyleEdges rather than the current fill of kQ3FillStyleFilled but
- * then we couldn't see the attributes on the vertex and face.
- */
- if ((status = Q3Mesh_GetEdgeVertices(meshGeo, meshEdge, &meshVertex1, &meshVertex2)) == kQ3Failure) {
- return status;
- }
-
- /* Get the vertex attributes */
- if (((status = Q3Mesh_GetVertexAttributeSet(meshGeo, meshVertex1, &attributeSet1)) == kQ3Failure) ||
- ((status = Q3Mesh_GetVertexAttributeSet(meshGeo, meshVertex2, &attributeSet2)) == kQ3Failure)) {
- goto ChangeMeshEdgeColor_Exit;
- }
-
- /* Create an attributes if none */
- if (attributeSet1 == NULL) {
- if ((attributeSet1 = Q3AttributeSet_New()) == NULL) {
- goto ChangeMeshEdgeColor_Exit;
- }
- }
-
- if (attributeSet2 == NULL) {
- if ((attributeSet2 = Q3AttributeSet_New()) == NULL) {
- goto ChangeMeshEdgeColor_Exit;
- }
- }
-
- GetRandomRGBColor(&colorRGB);
- if (((status = Q3AttributeSet_Add(attributeSet1, kQ3AttributeTypeDiffuseColor, &colorRGB)) == kQ3Success) &&
- ((status = Q3AttributeSet_Add(attributeSet2, kQ3AttributeTypeDiffuseColor, &colorRGB)) == kQ3Success)) {
-
- char partTypeString[] = {"\pEdge"};
-
- /* Set new vertex color */
- if (((status = Q3Mesh_SetVertexAttributeSet(meshGeo, meshVertex1, attributeSet1)) == kQ3Success) &&
- ((status = Q3Mesh_SetVertexAttributeSet(meshGeo, meshVertex2, attributeSet2)) == kQ3Success)) {
-
- /* Redraw the mesh */
- DrawDocumentData(theDocument);
- MoveTo(kTextLocationX, kTextLocationY);
- DrawText((void *) partTypeString, 1, (short) partTypeString[0]);
- TickDelay(kDelay);
- }
-
- /* Remove new vertex color */
- status = Q3Mesh_SetVertexAttributeSet(meshGeo, meshVertex1, NULL);
- status = Q3Mesh_SetVertexAttributeSet(meshGeo, meshVertex2, NULL);
- DrawDocumentData(theDocument);
- }
-
- ChangeMeshEdgeColor_Exit:
-
- if (attributeSet1 != NULL)
- Q3Object_Dispose(attributeSet1);
-
- if (attributeSet2 != NULL)
- Q3Object_Dispose(attributeSet2);
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // ChangeMeshVertexColor
-
- static
- TQ3Status ChangeMeshVertexColor(
- TQ3GeometryObject meshGeo,
- TQ3MeshVertex meshVertex,
- DocumentPtr theDocument)
- {
- TQ3Status status;
- TQ3AttributeSet attributeSet;
- TQ3ColorRGB colorRGB;
-
- status = kQ3Failure;
-
- if ((meshGeo == NULL) ||
- (meshVertex == NULL) ||
- (theDocument == NULL)) {
- debugstr("ChangeMeshVertexColor: NULL parameter passed");
- return status;
- }
-
- /* Get the vertex attributes */
- if ((status = Q3Mesh_GetVertexAttributeSet(meshGeo, meshVertex, &attributeSet)) == kQ3Failure) {
- return status;
- }
-
- /* Create an attributes if none */
- if (attributeSet == NULL) {
- if ((attributeSet = Q3AttributeSet_New()) == NULL) {
- return kQ3Failure;
- }
- }
-
- GetRandomRGBColor(&colorRGB);
- if ((status = Q3AttributeSet_Add(attributeSet, kQ3AttributeTypeDiffuseColor, &colorRGB)) == kQ3Success) {
-
- char partTypeString[] = {"\pVertex"};
-
- /* Set new vertex color */
- status = Q3Mesh_SetVertexAttributeSet(meshGeo, meshVertex, attributeSet);
-
- /* Redraw the mesh */
- DrawDocumentData(theDocument);
- MoveTo(kTextLocationX, kTextLocationY);
- DrawText((void *) partTypeString, 1, (short) partTypeString[0]);
- TickDelay(kDelay);
-
- /* Remove new vertex color */
- status = Q3Mesh_SetVertexAttributeSet(meshGeo, meshVertex, NULL);
- DrawDocumentData(theDocument);
- }
-
- Q3Object_Dispose(attributeSet);
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // HandleMeshShapePart
-
- static
- TQ3Status HandleMeshShapePart(
- TQ3GeometryObject geometry,
- TQ3ShapePartObject shapePart,
- DocumentPtr theDocument)
- {
- TQ3Status status;
- TQ3ObjectType objectType;
-
- if ((geometry == NULL) || (shapePart == NULL) || (theDocument == NULL)) {
- debugstr("HandleMeshShapePart: NULL parameter passed");
- return kQ3Failure;
- }
-
- /* Is object a mesh geometry? */
- if (Q3Object_IsType (geometry, kQ3GeometryTypeMesh) == kQ3False) {
- debugstr("HandleMeshShapePart: geometry isn't a mesh");
- return kQ3Failure;
- }
-
- /* Is the shapePart a mesh part? */
- if (Q3ShapePart_GetType (shapePart) != kQ3ShapePartTypeMeshPart) {
- debugstr("HandleMeshShapePart: shape part isn't for a mesh");
- return kQ3Failure;
- }
-
- status = kQ3Failure;
-
- /* Or use this to get the shape part hit: objectType = Q3Object_GetLeafType(shapePart); */
- objectType = Q3MeshPart_GetType(shapePart);
-
- switch (objectType) {
- case kQ3MeshPartTypeMeshFacePart:
- {
- TQ3MeshFace meshFace;
-
- if (Q3MeshFacePart_GetFace(shapePart, &meshFace) == kQ3Success) {
- status = ChangeMeshFaceColor(geometry, meshFace, theDocument);
- }
- }
- break;
-
- case kQ3MeshPartTypeMeshEdgePart:
- {
- TQ3MeshEdge meshEdge;
-
- if (Q3MeshEdgePart_GetEdge(shapePart, &meshEdge) == kQ3Success) {
- status = ChangeMeshEdgeColor(geometry, meshEdge, theDocument);
- }
- }
- break;
-
- case kQ3MeshPartTypeMeshVertexPart:
- {
- TQ3MeshVertex meshVertex;
-
- if (Q3MeshVertexPart_GetVertex(shapePart, &meshVertex) == kQ3Success) {
- status = ChangeMeshVertexColor(geometry, meshVertex, theDocument);
- }
- }
- break;
-
- default:
- status = kQ3Failure;
- break;
- }
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // HandleMeshPickHits
-
- static
- TQ3Status HandleMeshPickHits(
- TQ3PickObject pick,
- DocumentPtr theDocument)
- {
- TQ3Status status;
- unsigned long hitIndex,
- numHits;
- #if defined(QD3D_OBSOLETE) && QD3D_OBSOLETE
- TQ3HitData hitData;
- #else /* ! QD3D_OBSOLETE */
- TQ3PickDetail validMask;
- TQ3Object object;
- TQ3ShapePartObject shapePart;
-
- object = NULL;
- shapePart = NULL;
- #endif /* ! QD3D_OBSOLETE */
-
-
- if ((pick == NULL) || (theDocument == NULL)) {
- debugstr("HandleMeshPickHits: NULL parameter passed");
- return kQ3Failure;
- }
-
- numHits = 0;
- if (Q3Pick_GetNumHits(pick, &numHits) == kQ3Failure) {
- debugstr("HandleMeshPickHits: NULL parameter passed");
- return kQ3Failure;
- }
-
- /* Process each hit in the pick */
- for (hitIndex = 0, status = kQ3Success;
- (hitIndex < numHits) && (status == kQ3Success);
- hitIndex++) {
-
- #if defined(QD3D_OBSOLETE) && QD3D_OBSOLETE
-
- if (Q3Pick_GetHitData(pick, hitIndex, &hitData) == kQ3Failure) {
- debugstr("HandleMeshPickHits: Q3Pick_GetHitData failed");
- status = kQ3Failure;
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Test if hit data contains an object and shape part */
-
- /* Get reference to geometry object hit */
- if (! HitData_Has_Object(hitData)) {
- debugstr("HandleMeshPickHits: no object information returned in Q3Pick_GetHitData");
- status = kQ3Failure;
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Get reference to shapePart hit */
- if (! HitData_Has_ShapePart(hitData)) {
- debugstr("HandleMeshPickHits: no shape part information returned in Q3Pick_GetHitData");
- status = kQ3Failure;
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Color the shape part(s) hit */
- (void) HandleMeshShapePart(hitData.object, hitData.shapePart, theDocument);
-
- /* Dispose hitData.object and hitData.shapePart returned with Q3Pick_GetHitData */
- HandleMeshPickHits_Cleanup:
- Q3Hit_EmptyData(&hitData);
-
- #else /* ! QD3D_OBSOLETE */
-
- /*
- * New Picking API for QuickDraw 3D Release 1.5
- */
-
- /* Get the TQ3PickDetail masks for this hit (hitIndex) */
- if ((status = Q3Pick_GetPickDetailValidMask(pick, hitIndex, &validMask)) == kQ3Failure) {
- debugstr("HandleMeshPickHits: Q3Pick_GetPickDetailValidMask failed");
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Quick check to see if the hit contains an object and shape part */
- if (! (validMask & kQ3PickDetailMaskObject) ||
- ! (validMask & kQ3PickDetailMaskShapePart) ) {
- debugstr("HandleMeshPickHits: expected object and shapePart TQ3PickDetailMasks masks to be set");
- status = kQ3Failure;
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Get reference to geometry object hit */
- if ((status = Q3Pick_GetPickDetailData(pick, hitIndex, kQ3PickDetailMaskObject, &object)) == kQ3Failure) {
- debugstr("HandleMeshPickHits: no object returned in Q3Pick_GetPickDetailData");
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Get reference to shapePart hit */
- if ((status = Q3Pick_GetPickDetailData(pick, hitIndex, kQ3PickDetailMaskShapePart, &shapePart)) == kQ3Failure) {
- debugstr("HandleMeshPickHits: no object returned in Q3Pick_GetPickDetailData");
- goto HandleMeshPickHits_Cleanup;
- }
-
- /* Color the shape part(s) hit */
- (void) HandleMeshShapePart(object, shapePart, theDocument);
-
- /* Dispose object and shapePart returned with Q3Pick_GetPickDetailData */
- HandleMeshPickHits_Cleanup:
- if (object != NULL) {
- Q3Object_Dispose(object);
- object = NULL;
- }
- if (shapePart != NULL) {
- Q3Object_Dispose(shapePart);
- shapePart = NULL;
- }
-
- #endif /* ! QD3D_OBSOLETE */
- }
-
-
- /*
- * If we reuse the pick object be sure to empty the hit list.
- * If the pick object is disposed immediately after picking
- * (not the case in this sample code) the hit list is automatically disposed.
- */
- if (Q3Pick_EmptyHitList(pick) == kQ3Failure) {
- debugstr("HandleMeshPickHits: Q3Pick_EmptyHitList failed");
- }
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // CreatePick
-
- static
- TQ3Status CreatePick(
- TQ3PickObject *pPick)
- {
- TQ3WindowPointPickData data;
- TQ3Status status;
-
- status = kQ3Failure;
-
- if (pPick == NULL)
- return status;
-
- /* Create pick object */
- data.data.sort = kQ3PickSortNearToFar;
- data.data.mask = kQ3PickDetailMaskObject | /* Request only object and shape parts */
- kQ3PickDetailMaskShapePart;
- data.data.numHitsToReturn = kQ3ReturnAllHits;
-
- Q3Point2D_Set(&data.point, 0.0, 0.0);
- data.vertexTolerance = 5.0; /* Set vertex and edge tolerences */
- data.edgeTolerance = 3.0;
-
- if ((*pPick = Q3WindowPointPick_New(&data)) != NULL)
- status = kQ3Success;
-
- return status;
- }
-
-
- //-----------------------------------------------------------------------------
- //
- // DoPicking
-
- TQ3Status DoPicking(
- Point *pWhere, /* local window coordinates */
- DocumentPtr theDocument)
- {
- TQ3Status status;
- TQ3Point2D point;
-
- status = kQ3Failure;
-
- if (theDocument->fView == NULL ||
- theDocument->fModel == NULL ||
- theDocument->fPickPartStyle == NULL ||
- gPick == NULL) {
-
- return kQ3Failure;
- }
-
- /* Set pick part style with parts selected in the menu */
- if ((status = Q3PickPartsStyle_Set(theDocument->fPickPartStyle, theDocument->fPickParts)) == kQ3Failure)
- return kQ3Failure;
-
- /* Set the pick's point to mouse location */
- Q3Point2D_Set(&point, pWhere->h, pWhere->v);
- if ((status = Q3WindowPointPick_SetPoint(gPick, &point)) == kQ3Failure)
- return kQ3Failure;
-
- if ((status = DoGroupPicking(theDocument->fView, theDocument->fModel, gPick)) == kQ3Failure)
- return kQ3Failure;
-
- /* Handle hit(s) on mesh */
- return HandleMeshPickHits(gPick, theDocument);
- }
-